package com.htgd.gardenexpo.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.htgd.gardenexpo.dto.GeConPlantDTO;
import com.htgd.gardenexpo.entity.CommonResult;
import com.htgd.gardenexpo.entity.GeConPlant;
import com.htgd.gardenexpo.entity.GeConPlantImg;
import com.htgd.gardenexpo.page.PlantQuery;
import com.htgd.gardenexpo.service.GeConPlantImgService;
import com.htgd.gardenexpo.service.GeConPlantService;
import com.htgd.gardenexpo.utils.WeChatUtils;
import com.htgd.gardenexpo.vo.GeConPlantVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;




import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.htgd.gardenexpo.controller.GardenexpoController.getFirstLetter;

/**
 * <p>
 * 植物百科 前端控制器
 * </p>
 *
 * @author author
 * @since 2024-08-23
 */
@RestController
@RequestMapping("/api/plant")
@Api(tags = "植物百科")
@Slf4j
public class GeConPlantController {

    @Autowired
    private GeConPlantService geConPlantService;

    @Autowired
    private GeConPlantImgService geConPlantImgService;

    @Autowired
    private WeChatUtils weChatUtils;

    @Value("${generate.plant}")
    public String plantUrl;

    @Value("${wx.public.appId}")
    private String appId;

    @Value("${wx.public.appsecret}")
    private String appsecret;

    private static final int WIDTH = 300;
    private static final int HEIGHT = 300;


    @PostMapping(value = "/add")
    @ApiOperation("添加")
    @Transactional
    public CommonResult<JSONObject> add(@RequestBody GeConPlantDTO geConPlantDTO) {
        CommonResult<JSONObject> result = new CommonResult<>();
        try {
            GeConPlant geConPlant = new GeConPlant();
            BeanUtils.copyProperties(geConPlantDTO,geConPlant);
            //索引
            char firstLetter = getFirstLetter(geConPlant.getNameZh());
            geConPlant.setIndex(String.valueOf(firstLetter));
            //其它默认属性
            geConPlant.setCreateTime(LocalDateTime.now());
            geConPlant.setStatus(String.valueOf(4));
            geConPlantService.save(geConPlant);
            //图片
            List<String> images = geConPlantDTO.getImages();
            for (String image : images) {
                GeConPlantImg geConPlantImg = new GeConPlantImg();
                geConPlantImg.setBotanyId(geConPlant.getId());
                geConPlantImg.setCreateTime(LocalDateTime.now());
                geConPlantImg.setFileName(image);
                geConPlantImgService.save(geConPlantImg);
            }
            result.setCode(200);
            result.setMessage("添加成功");
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @PostMapping(value = "/edit")
    @ApiOperation("编辑")
    public CommonResult<JSONObject> edit(@RequestBody GeConPlantDTO geConPlantDTO) {
        CommonResult<JSONObject> result = new CommonResult<>();
        try {
            GeConPlant geConPlant = new GeConPlant();
            BeanUtils.copyProperties(geConPlantDTO,geConPlant);
            //索引
            char firstLetter = getFirstLetter(geConPlant.getNameZh());
            geConPlant.setIndex(String.valueOf(firstLetter));
            //其它默认属性
            geConPlant.setStatus(String.valueOf(4));
            geConPlant.setUpdateTime(LocalDateTime.now());
            geConPlantService.updateById(geConPlant);
            //图片
            QueryWrapper<GeConPlantImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("botany_id",geConPlantDTO.getId());
            geConPlantImgService.remove(queryWrapper);
            List<String> images = geConPlantDTO.getImages();
            for (String image : images) {
                GeConPlantImg geConPlantImg = new GeConPlantImg();
                geConPlantImg.setBotanyId(geConPlant.getId());
                geConPlantImg.setCreateTime(LocalDateTime.now());
                geConPlantImg.setFileName(image);
                geConPlantImgService.save(geConPlantImg);
            }
            result.setCode(200);
            result.setMessage("修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @DeleteMapping(value = "/delete")
    @ApiOperation("删除")
    @Transactional
    public CommonResult<JSONObject> delete(String id) {
        CommonResult<JSONObject> result = new CommonResult<>();
        try {
            geConPlantService.removeById(id);
            QueryWrapper<GeConPlantImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("botany_id",id);
            geConPlantImgService.remove(queryWrapper);
            result.setCode(200);
            result.setMessage("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @GetMapping(value = "/list")
    @ApiOperation("查询")
    public CommonResult<List<GeConPlantVO>> list(PlantQuery plantQuery) {
        CommonResult<List<GeConPlantVO>> result = new CommonResult<>();
        try {
            PageInfo<GeConPlantVO> list = geConPlantService.pageList(plantQuery);
            result.setCode(200);
            result.setMessage(String.valueOf(list.getTotal()));
            result.setData(list.getList());
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @GetMapping(value = "/plantList")
    @ApiOperation("小程序查询")
    public CommonResult<List<GeConPlantVO>> plantList() {
        CommonResult<List<GeConPlantVO>> result = new CommonResult<>();
        try {
            List<GeConPlantVO> list = geConPlantService.plantList();
            result.setCode(200);
            result.setMessage(String.valueOf(list.size()));
            result.setData(list);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @GetMapping(value = "/details")
    @ApiOperation("详情")
    public CommonResult<GeConPlantVO> details(String id) {
        CommonResult<GeConPlantVO> result = new CommonResult<>();
        try {
            GeConPlantVO geConPlantVO = new GeConPlantVO();
            GeConPlant geConPlant = geConPlantService.getById(id);
            BeanUtils.copyProperties(geConPlant,geConPlantVO);
            //图片
            List<String> images = new ArrayList<>();
            QueryWrapper<GeConPlantImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("botany_id",id);
            List<GeConPlantImg> geConPlantImgs = geConPlantImgService.list(queryWrapper);
            for (GeConPlantImg geConPlantImg : geConPlantImgs) {
                images.add(geConPlantImg.getFileName());
            }
            geConPlantVO.setImages(images);
            result.setCode(200);
            result.setMessage("查询成功");
            result.setData(geConPlantVO);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @PostMapping(value = "/review")
    @ApiOperation("审核")
    public CommonResult<JSONObject> review(@RequestBody GeConPlant geConPlant) {
        CommonResult<JSONObject> result = new CommonResult<>();
        try {
            geConPlantService.updateById(geConPlant);
            result.setCode(200);
            result.setMessage("成功");
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(500);
        }
        return result;
    }

    @GetMapping(value = "/download")
    @ApiOperation("下载")
    public ResponseEntity<byte[]> download(String page) {
        try {
            // 设置二维码生成的参数
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            Map<EncodeHintType, Object> hintMap = new HashMap<>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 使用 UTF-8 编码

            // 生成二维码
            BitMatrix bitMatrix = qrCodeWriter.encode(page, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hintMap);

            // 将 BitMatrix 转换为 BufferedImage
            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            for (int y = 0; y < HEIGHT; y++) {
                for (int x = 0; x < WIDTH; x++) {
                    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }

            // 将 BufferedImage 写入 ByteArrayOutputStream
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", baos);
            byte[] imageBytes = baos.toByteArray();

            // 设置 HTTP 响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(imageBytes.length);
            headers.setContentDispositionFormData("attachment", "QRCode.png");

            return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);

        } catch (WriterException | IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(e.toString().getBytes(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    @GetMapping(value = "/downloadNew")
    @ApiOperation("微信二维码下载")
    public ResponseEntity<byte[]> downloadNew(String page,String id) {
        log.info("植物百科-微信二维码下载：{},{}",page,id);
        try {
            //获取token
            String accessToken = weChatUtils.getAccessToken(appId, appsecret);

            byte[] qrCode = weChatUtils.createQRCode(accessToken, page, id);

            // 设置 HTTP 响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(qrCode.length);
            headers.setContentDispositionFormData("attachment", "QRCode.png");

            return new ResponseEntity<>(qrCode, headers, HttpStatus.OK);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(e.toString().getBytes(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @GetMapping(value = "/downloadBatch")
    @ApiOperation("批量下载")
    public ResponseEntity<byte[]> downloadBatch() {
        log.info("植物百科-批量下载");
        try {
            List<GeConPlant> list = geConPlantService.lambdaQuery().eq(GeConPlant::getStatus, "3").list();

            // 临时存放二维码文件
            List<byte[]> qrCodes = new ArrayList<>();

            //获取token
            String accessToken = weChatUtils.getAccessToken(appId, appsecret);

            for (GeConPlant geConPlant : list) {
                byte[] qrCode = weChatUtils.createQRCode(accessToken, "pages/park-science/plant-science-detail", geConPlant.getId());
                qrCodes.add(qrCode);
            }

            // 创建一个字节输出流用于存储 ZIP 数据
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
                for (int i = 0; i < qrCodes.size(); i++) {
                    byte[] qrCode = qrCodes.get(i);
                    ZipEntry zipEntry = new ZipEntry(list.get(i).getNameZh() +list.get(i).getId()+ ".png");
                    zipOutputStream.putNextEntry(zipEntry);
                    zipOutputStream.write(qrCode);
                    zipOutputStream.closeEntry();
                }
            }

            // 设置 HTTP 响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentLength(byteArrayOutputStream.size());
            headers.setContentDispositionFormData("attachment", "植物百科图片.zip");

            return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(e.toString().getBytes(), HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

}
